__metaclass__ = type

from proxy import proxy

class quantifier:

    def __init__(self, name, item, required=False, single=False):
        self.name = name
        self.item = item
        self.required = required
        self.single = single

    def __getattribute__(self, attr):
        if attr in ['__repr__', '__len__', 'name',
                    'required', 'single', 'item', 'copy']:
            return object.__getattribute__(self, attr)
        target = self.item
        if isinstance(target, proxy):
            target = target.item
        return object.__getattribute__(target, attr)

    def copy(self, **kw):
        k = {'name':self.name,
             'item':self.item,
             'required':self.required,
             'single':self.single}
        k.update(kw)
        return quantifier(**k)

    def __len__(self):
        return len(self.item)

    def __call__(self, value):
        return self.item(value)

    def __repr__(self):
        if not self.name:
            return str(self.item)
        return '(%s)%s' % (self.item, self.name)

def one(item, required=True, single=True):
    return quantifier('', item, required=required, single=single)

def opt(item, required=False, single=True):
    return quantifier('?', item, required=required, single=single)

def oneOrMore(item, required=True, single=False):
    return quantifier('+', item, required=required, single=single)

def zeroOrMore(item, required=False, single=False):
    return quantifier('*', item, required=required, single=single)

